/*
 * Copyright (C) 2012, 2016 DuckDuckGo, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* global DEBUG, RELOADER, BUILD_TARGET */

import { onStartup } from './startup';
import FireButton from './components/fire-button';
import TabTracker from './components/tab-tracking';
import MV3ContentScriptInjection from './components/mv3-content-script-injection';
import EmailAutofill from './components/email-autofill';
import OmniboxSearch from './components/omnibox-search';
import InternalUserDetector from './components/internal-user-detector';
import TDSStorage from './components/tds';
import ToggleReports from './components/toggle-reports';
import TrackersGlobal from './components/trackers';
import DebuggerConnection from './components/debugger-connection';
import Devtools from './components/devtools';
import DNRListeners from './components/dnr-listeners';
import RemoteConfig from './components/remote-config';
import DashboardMessaging from './components/dashboard-messaging';
import initDebugBuild from './devbuild';
import initReloader from './devbuild-reloader';
import tabManager from './tab-manager';
import AbnExperimentMetrics, { setUpTestExperiment } from './components/abn-experiments';
import MessageRouter from './components/message-router';
import RequestBlocklist from './components/request-blocklist';
import { AppUseMetric, SearchMetric, DashboardUseMetric, RefreshMetric } from './metrics';
// NOTE: this needs to be the first thing that's require()d when the extension loads.
// otherwise FF might miss the onInstalled event
require('./events');
const settings = require('./settings');
if (BUILD_TARGET === 'chrome') {
    require('./dnr-config-rulesets');
}

settings.ready().then(() => {
    onStartup();
});

const remoteConfig = new RemoteConfig({ settings });
const abnMetrics = BUILD_TARGET !== 'firefox' ? new AbnExperimentMetrics({ remoteConfig }) : null;
const tds = new TDSStorage({ settings, remoteConfig, abnMetrics });
const devtools = new Devtools({ tds });
const dashboardMessaging = new DashboardMessaging({ settings, tds, tabManager });
/**
 * @type {{
 *  autofill: EmailAutofill;
 *  dashboardMessaging: DashboardMessaging
 *  omnibox: OmniboxSearch;
 *  fireButton?: FireButton;
 *  internalUser: InternalUserDetector;
 *  tds: TDSStorage;
 *  tabTracking: TabTracker;
 *  toggleReports: ToggleReports;
 *  trackers: TrackersGlobal;
 *  remoteConfig: RemoteConfig;
 *  abnMetrics: AbnExperimentMetrics?;
 *  messaging: MessageRouter;
 * }}
 */
const components = {
    autofill: new EmailAutofill({ settings }),
    dashboardMessaging,
    omnibox: new OmniboxSearch(),
    internalUser: new InternalUserDetector({ settings }),
    tabTracking: new TabTracker({ tabManager, devtools, abnMetrics }),
    tds,
    toggleReports: new ToggleReports({ dashboardMessaging }),
    trackers: new TrackersGlobal({ tds }),
    debugger: new DebuggerConnection({ tds, devtools }),
    devtools,
    remoteConfig,
    abnMetrics,
    messaging: new MessageRouter({ tabManager }),
};

// Chrome-only components
if (BUILD_TARGET === 'chrome' || BUILD_TARGET === 'chrome-mv2') {
    components.metrics = [
        new AppUseMetric({ abnMetrics }),
        new SearchMetric({ abnMetrics }),
        new DashboardUseMetric({ abnMetrics, messaging: components.messaging }),
        new RefreshMetric({
            abnMetrics,
            tabTracking: components.tabTracking,
        }),
    ];
    components.fireButton = new FireButton({ settings, tabManager });
    setUpTestExperiment(abnMetrics);
}

if (BUILD_TARGET === 'chrome') {
    // MV3-only components
    components.scriptInjection = new MV3ContentScriptInjection();
    components.dnrListeners = new DNRListeners({ settings, tds });
} else {
    // MV2-only components
    components.requestBlocklist = new RequestBlocklist();
}
console.log(new Date(), 'Loaded components:', components);
// @ts-ignore
self.components = components;

// Optional features controlled by build flags.
// If these flags are set to false, the whole function is tree-shaked from the build.
DEBUG && initDebugBuild();
RELOADER && initReloader();
